﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Upgrade
{
    /// <summary>
    /// TraceEx 程序代码跟踪。
    /// 
    /// Trace 中相应的功能先不增加
    /// </summary>
    /// [System.Diagnostics.DebuggerStepThrough()]
    public class TraceEx
    {
        private static bool _HshGetConfigInfo = false;
        private static bool _RequireSaveCodeRunInfo = false;

        private static DateTime _LastWriteDate;
        private static string _LastWriteMessage;
        private static readonly string APP_PATH = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase;
        private static readonly string APP_ROOT = System.IO.Path.GetDirectoryName(APP_PATH);
        private static string _APP_TEMP_PATH = APP_ROOT + @"\temp";

        private static string SaveCodeRunInfo = "true";// UserSettings.Instance.AppSettings["SaveCodeRunInfo"];
        private static string AppLogFile = "App.Run.Log";//UserSettings.Instance.AppSettings["AppLogFile"];
        static TraceEx()
        {
            _LastWriteDate = System.DateTime.Now;
        }
        /// <summary>
        /// 在系统登录之前检查并删除日记文件。
        /// </summary>
        public static void CheckAndDeleteLogFile()
        {
            try
            {
                if (Directory.Exists(_APP_TEMP_PATH))
                    Directory.Delete(_APP_TEMP_PATH);
            }
            catch { }
        }

        /// <summary>
        /// 应用程序的临时目录设置。
        /// </summary>
        public static string APP_TEMP_PATH
        {
            get
            {
                return _APP_TEMP_PATH;
            }
            set
            {
                _APP_TEMP_PATH = value;
                if (!Directory.Exists(_APP_TEMP_PATH))
                    Directory.CreateDirectory(_APP_TEMP_PATH);
            }
        }

        #region Write ... 静态方法
        /// <summary>
        /// 把运行的代码过程记录下来
        /// </summary>
        /// <param name="msgStr"></param>
        public static void Write(string msgStr)
        {
            Write(msgStr, SysMessageLevel.CodeRunInfo);
        }
        /// <summary>
        /// 把运行的代码过程记录下来
        /// </summary>
        /// <param name="msgStr"></param>
        /// <param name="msgLevel"></param>
        public static void Write(string msgStr, SysMessageLevel msgLevel)
        {
            WriteIf(false, msgStr, msgLevel);
        }
        #endregion Write ...

        #region WriteIf...
        /// <summary>
        ///  根据条件把运行的代码过程记录下来
        /// </summary>
        /// <param name="condition"></param>
        /// <param name="msgStr"></param>
        public static void WriteIf(bool condition, string msgStr)
        {
            WriteIf(condition, msgStr, SysMessageLevel.CodeRunInfo);
        }
        /// <summary>
        /// 根据条件把运行的代码过程记录下来
        /// </summary>
        /// <param name="condition">condition ：如果要禁止显示消息，那么为true,否则为false</param>
        /// <param name="msgStr"></param>
        /// <param name="msgLevel"></param>
        public static void WriteIf(bool condition, string msgStr, SysMessageLevel msgLevel)
        {
            SaveIf(condition, msgStr, msgLevel, null);
        }

        #endregion WriteIf...

        #region 显示断言...
        /// <summary>
        /// 
        /// </summary>
        /// <param name="condition">condition ：如果要禁止显示消息，那么为true,否则为false  </param>
        /// <param name="msg"></param>
        public static void Assert(bool condition, string msg)
        {
            Assert(condition, msg, "");
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="condition">condition ：如果要禁止显示消息，那么为true,否则为false</param>
        /// <param name="msg"></param>
        /// <param name="detailMsg"></param>
        public static void Assert(bool condition, string msg, string detailMsg)
        {
            //Debug.Assert(condition, msg, detailMsg);
            SaveIf(condition, msg + detailMsg, SysMessageLevel.CodeRunInfo, null);
        }
        #endregion 显示断言...

        /// <summary>
        /// 
        /// </summary>
        /// <param name="condition"> condition ：如果要禁止写入消息，那么为true,否则为false</param>
        /// <param name="msgStr"></param>
        /// <param name="msgLevel"></param>
        /// <param name="fullPath"></param>
        /// <returns></returns>
        public static bool SaveIf(bool condition, string msgStr, SysMessageLevel msgLevel, string fullPath)
        {
            if (condition)
            {
                return true;
            }
            //显示给用户看的消息不需要存储
            if (msgLevel == SysMessageLevel.DisplayToUser)
            {
                return true;
            }
            //判断是否为记录代码运行的信息，如果是，将根据应用程序的配置来决定是否存储
            if (msgLevel == SysMessageLevel.CodeRunInfo)
            {
                if (!_HshGetConfigInfo)
                {
                    string str = string.Empty;
                    if (!string.IsNullOrEmpty(SaveCodeRunInfo))
                        str = SaveCodeRunInfo.ToString();
                    if (string.IsNullOrEmpty(str))
                    {
                        return true;
                    }
                    else
                    {
                        _RequireSaveCodeRunInfo = (str == "Y") || (str == "1") || (str.ToLower() == "true");
                    }
                    _HshGetConfigInfo = true;
                }
                if (!_RequireSaveCodeRunInfo) { return true; }
            }
            //避免重复存储大量的代码运行消息
            if (string.Compare(msgStr, _LastWriteMessage, true) == 0)
            {
                TimeSpan span = DateTime.Now.Subtract(_LastWriteDate);
                if (span.TotalMinutes < 1)
                { //如果在一分钟之内，那么没必要存储重复的信息
                    _LastWriteDate = DateTime.Now;
                    return true;
                }
            }
            else
            {
                _LastWriteMessage = msgStr;
            }
            _LastWriteDate = DateTime.Now;

            string tfullPath = fullPath;
            if (string.IsNullOrEmpty(tfullPath))
            {
                string logFile = string.Empty;
                if (AppLogFile != null)
                    logFile = AppLogFile.ToString();
                if (string.IsNullOrEmpty(logFile))
                {
                    logFile = "App.Run.Log";
                }
                //对于程序的日记加上时间来控制文件的大小
                string curDate = "(" + DateTime.Now.ToShortDateString() + ")";
                tfullPath = APP_TEMP_PATH;
                bool fb = System.IO.Directory.Exists(tfullPath);
                if (!fb)
                {
                    System.IO.Directory.CreateDirectory(tfullPath);
                }
                tfullPath = tfullPath + @"\" + curDate + logFile;
            }
            bool b = System.IO.File.Exists(tfullPath);
            if (!b)
            {
                //System.IO.File.CreateText(fullPath) ;
            }
            StreamWriter swFile = null;
            try
            {
                swFile = new StreamWriter(tfullPath, true);
                string errTypeStr = getErrType(msgLevel) + "-->";
                string strLine = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:") + errTypeStr + msgStr;
                swFile.WriteLine(strLine);
            }
            catch
            {

            }
            finally
            {
                if (swFile != null)
                {
                    swFile.Flush();
                    swFile.Close();
                }
            }
            return true;
        }
        private static string getErrType(SysMessageLevel msgLevel)
        {
            switch (msgLevel)
            {
                case SysMessageLevel.CodeRunInfo:
                    return "代码执行轨迹";
                case SysMessageLevel.SysDatabaseInfo:
                    return "数据库操作失败";
                case SysMessageLevel.SysErrInfo:
                    return "系统错误";
                case SysMessageLevel.SysFileInfo:
                    return "硬盘文件操作失败";
                case SysMessageLevel.OtherSysInfo:
                    return "代码执行失败";
                case SysMessageLevel.WebService:
                    return "WebService 访问";
                default:
                    return "其它信息";

            }

        }

        //by hanlx modify  20120221  
        public static string ReadIf(bool condition, string FileName)
        {
            if (condition)
            {
                return string.Empty;
            }

            string _sResult = string.Empty;

            string tfullPath = APP_ROOT + @"\" + FileName;

            if (System.IO.File.Exists(tfullPath))
            {
                try
                {
                    using (StreamReader sr = new StreamReader(tfullPath, System.Text.Encoding.Default))
                    {
                        String line;
                        // Read and display lines from the file until the end of 
                        // the file is reached.
                        while ((line = sr.ReadLine()) != null)
                        {
                            if (line.Trim() != "")
                            {
                                _sResult += line.Trim() + Environment.NewLine;
                            }
                        }
                    }
                }
                catch
                {
                }
            }

            return _sResult;
        }


    }

    /// <summary>
    /// 出错提示信息的等级
    /// </summary>
    public enum SysMessageLevel
    {
        SysErrInfo, //系统异常
        SysDatabaseInfo,//数据库操作异常
        SysFileInfo, //硬盘文件操作异常
        DisplayToUser, //显示给用户的异常信息
        CodeRunInfo, // 代码运行的信息 供开发人员做调试用
        SysWarning, //系统警告
        WebService, //WEB 服务访问出错
        OtherSysInfo,//其它系统异常
    }
}
